<!DOCTYPE html>
<html>
<head>
	<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
	<title>EaselJS Tutorial: Mouse Interaction</title>
	<link href="../_shared/tutorial.css" rel="stylesheet" type="text/css">
	<script src="../_shared/tutorial.js"></script>
	
	<!-- SyntaxHighlighter-->
	<script src="../_shared/SyntaxHighlighter/shCore.js"></script>
	<script src="../_shared/SyntaxHighlighter/shBrushJScript.js"></script>
	<script src="../_shared/SyntaxHighlighter/shBrushXml.js"></script>
	<link href="../_shared/SyntaxHighlighter/shCore.css" rel="stylesheet" type="text/css">
	<link href="../_shared/SyntaxHighlighter/shThemeCreateJS.css" rel="stylesheet" type="text/css">
</head>
	
<body onLoad="initTutorial();">
	<article>
		<header>
			<h1>EaselJS: Mouse Interaction</h1>
			<p>
				<strong>Synopsis:</strong> Learn about mouse events on display objects and the stage.<br>
				<strong>Topics:</strong> MouseEvent, addEventListener, on, click, dblclick, mouseover, mouseout,
				mousemove, mousedown, mouseup, enableMouseOver, drag and drop, mouseMoveOutside<br>
				<strong>Target:</strong> EaselJS v0.7.0
			</p>
		</header>
		<p class="highlight">
			This tutorial is part of the <a href="https://github.com/CreateJS/EaselJS/" target="_blank">EaselJS GitHub
			repository</a>.<br />
			Check out the repository for more tutorials and a handful of helpful samples.
		</p>

		<section>
			<header>
				<h2>The Basics</h2>
			</header>
			<p>
				At its core, the EaselJS mouse interaction model is very simple to use - just assign a listener to a
				mouse events via the <code>addEventListener</code> method on a display object:
				<textarea class="brush: js;" readonly>
circle.addEventListener("click", function(event) { alert("clicked"); })
				</textarea>
			</p>
			<iframe src="basic.html" class="demo" longDesc="the onClick handler" width="100%" height="220px"></iframe>
			<p>
				There are a number of events you can listen for on display objects: <code>click</code>,
				<code>mousedown</code>, <code>mouseup</code>, <code>dblclick</code>, <code>pressmove</code>,
				<code>pressup</code>, <code>mouseover</code> / <code>mouseout</code>, and <code>rollover</code> /
				<code>rollout</code>.
			</p>
			<p>
				The latter four events have some overhead associated with them, so you need to enable them with
				<code>stage.enableMouseOver(frequency)</code>. The <code>frequency</code> parameter indicates how many
				times per second EaselJS should calculate what is currently under the pointer. A higher number is more
				responsive, but also more computationally expensive. It defaults to 20 times per second.
			</p>
			<p>
				The <code>on</code> method provides a shortcut to <code>addEventListener</code>, and adds additional
				functionality. See the API docs for more details.
				<textarea class="brush: js;" readonly>
circle.on(type, listener, scope, once, data, useCapture);
							</textarea>
			</p>
		</section>
		
		<section>
			<header>
				<h2>MouseEvent</h2>
			</header>
			<p>
				When a mouse handler is triggered, it is called with a single parameter holding a MouseEvent instance.
				You can use this object to see what <code>type</code> of event it was, what the <code>target</code> was,
				get access to the <code>nativeEvent</code> object it was based on, and to check the pointer's
				<code>stageX</code> and <code>stageY</code> coordinates.
			<textarea class="brush: js;" readonly>
circle.on("click", function(evt) {
	alert("type: "+evt.type+" target: "+evt.target+" stageX: "+evt.stageX);
});
			</textarea>
			</p>
			<iframe src="events.html" class="demo" longDesc="demonstrating the different mouse event types on display objects" width="100%" height="220px"></iframe>
		</section>
		
		<section>
			<header>
				<h2>Bubbling</h2>
			</header>
			<p>
				When a mouse event is triggered on a target, the event flows through three phases: the capture phase,
				the target phase, and the bubbling phase.
			</p>
			<p>
				In the first phase (capture), the event is dispatched starting with the stage, and progressing through
				the ancestors of the target to its immediate parent.
				Only listeners that were added using the useCapture parameter are triggered in this phase.
			</p>
			<p>
				In the second phase (target), the event is dispatched on the target object (ex. the element that was
				clicked).
			</p>
			<p>
				In the final phase (bubbling), the event is dispatched from the immediate parent of the target through
				the ancestors (in the reverse order of the capture phase) to the stage.
			</p>
			<p>
				The example below has a "button", which is a <code>Container</code> instance containing two children: a
				background shape, and a text label. All three display objects and the stage have listeners for the
				"click" event both with and without the useCapture param.
			</p>
			<iframe src="bubbling.html" class="demo" longDesc="event bubbling" width="100%" height="120px"></iframe>
		</section>
		
		<section>
			<header>
				<h2>mouseChildren & mouseEnabled</h2>
			</header>
			<p>
				You can prevent the children of a <code>Container</code> from dispatching mouse events setting
				<code>mouseChildren</code> to <code>false</code>.
			<textarea class="brush: js;" readonly>
myContainer.mouseChildren = false;
			</textarea>
			</p>
			<p>
				This causes the container to be treated as an aggregate element for mouse interactions. For example, in
				the bubbling example above setting <code>button.mouseChildren = false;</code>
				would make it so that clicking children of the button (background & label) dispatches the click event
				with the button as the target instead of the child that was clicked.
			</p>
			<p>
				Similarly, you can completely disable mouse events on any display object without removing its handlers
				by setting <code>mouseEnabled</code> to <code>false</code>.
			<textarea class="brush: js;" readonly>
circle.on("click", function() { alert("Clicked!"); });
circle.mouseEnabled = false;
			</textarea>
		</section>
		
		<section>
			<header>
				<h2>hitArea</h2>
			</header>
			<p>
				Normally, EaselJS will calculate mouse hits on a display object based on its visible, non-transparent
				pixels. This usually works pretty well, but there may be cases where you want to define a hit target that is different than what is displayed on screen.
			</p>
			<p>
				To do this, you can assign any other display object to be the <code>hitArea</code> for your object.
				It does not need to be on the display list, and will not be visible, but it will be used for the hit test instead.
			</p>
			<p>
				Hit area display objects are used within the coordinate system (ie. concatenated transformation) of
				their owner, and as such you can reuse the same display object as the <code>hitArea</code> of multiple objects.
			</p>
			<iframe src="hitArea.html" class="demo" longDesc="mouse event handlers on containers" width="100%" height="170px"></iframe>
			<p>
				Notice how in this demo, as you roll over the red text, it only registers a hit when the pointer is
				over a non-transparent pixel, whereas the blue text uses the rectangular <code>hitArea</code> to calculate the hit.
			</p>
		</section>
			
		<section>
			<header>
				<h2>Stage mouse events</h2>
			</header>
			<p>
				For the stage, just like every other display object, you will only get events when the mouse is over a
				non-transparent pixel.
			</p>
			<p>
				Stage has a few special mouse events that come in handy for responding to general mouse interactions
				anywhere within your canvas. <code>stagemousedown</code>, <code>stagemouseup</code>, and
				<code>stagemousemove</code> are called any time a relevant mouse interaction happens anywhere on the
				canvas.
			<textarea class="brush: js;" readonly>
stage.on("stagemousedown", function(evt) {
	alert("the canvas was clicked at "+evt.stageX+","+evt.stageY);
})
			</textarea>
			<p>
				The following demo demonstrates using these events to let you finger paint on the canvas:
			</p>
			<iframe src="stage.html" class="demo" longDesc="using stagemousedown, stagemouseup & stagemousemove." width="100%" height="220px"></iframe>
			<p>
				By default, you will stop getting <code>stagemousemove</code> events whenever the pointer is outside of the canvas.
			</p>
			<p>
				If you'd like to keep getting <code>stagemousemove</code> events when the pointer leaves the canvas,
				just set <code>mouseMoveOutside</code> to <code>true</code>. The <code>stageX</code> &
				<code>stageY</code> properties of <code>MouseEvent</code> will always return a value normalized to
				within your stage bounds, but you can use <code>rawX</code> and <code>rawY</code> to get values that
				haven't been normalized (this can cause errors if you aren't careful).
			<textarea class="brush: js;" readonly>
stage.mouseMoveOutside = true;
stage.on("stagemousemove", function(evt) {
	console.log("stageX/Y: "+evt.stageX+","+evt.stageY); // always in bounds
	console.log("rawX/Y: "+evt.rawX+","+evt.rawY); // could be < 0, or > width/height
});
			</textarea>
			</p>
			<p>
				You can monitor whether the pointer is over the canvas by using <code>stage.mouseInBounds</code> and the
				<code>mouseleave</code> / <code>mouseenter</code> events.
			</p>
		</section>
		
		<section>
			<header>
				<h2>Drag and drop</h2>
			</header>
			<p>
				EaselJS makes drag and drop functionality very easy to implement. After the mouse is pressed over a
				display object, that object will generate <code>pressmove</code> events until the mouse is released, at
				which point a <code>pressup</code> event will be dispatched.
			</p>
			<textarea class="brush: js;" readonly>
circle.on("pressmove", function(evt) {
	evt.target.x = evt.stageX;
	evt.target.y = evt.stageY;
});
circle.on("pressup", function(evt) { console.log("up"); })
			</textarea>
			<p>
				Check out the source for the demo below for a simple example of this in action. It's also a great place
                to test out the <code>mouseMoveOutside</code> property.
			</p>
			<iframe src="drag.html" class="demo" longDesc="implementing drag and drop" width="100%" height="220px"></iframe>
		</section>
		
		<section>
			<header>
				<h2>Other useful APIs</h2>
			</header>
			<p>
				Other methods that are relevant to advanced mouse interactions are:<ul>
					<li> <code>Container.getObjectUnderPoint()</code> returns the top most display object under the
						specified point.</li>
					<li> <code>Container.getObjectsUnderPoint()</code> returns all display objects under the specified
						point.</li>
					<li> <code>DisplayObject.hitTest()</code> returns true if the specified point in the display object
						is non-transparent.</li>
				</ul>
				Check out the API documentation and the HitTest tutorial for more information.
			</p>
		</section>
		
	</article>
</body>
</html>
